/**
 * @author Ahammer
 * @date    2009 05
 * @update  2009 08 output color options
 */

/*
 * This file is part of Iqm.
 * Copyright (c) 2010-2011 Helmut Ahammer
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package opgui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import javax.media.jai.ParameterBlockJAI;
import javax.media.jai.PlanarImage;
import javax.swing.ButtonGroup;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JScrollBar;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import main.IqmTools;
import main.Tank;

public class IqmKMeansGUI  extends IqmOperatorJFrame
							    implements IqmOperatorGUIBuilder, ActionListener, AdjustmentListener {

	private  ParameterBlockJAI    pb         = null;  //  @jve:decl-index=0:
		
	private int    nK;     //k
 	private int    itMax;  //maximal iteration
	private double eps;    //epsilon
	

	private  JRadioButtonMenuItem buttEven 			= null;
	private  JRadioButtonMenuItem buttRandomSample	= null;
	private  JRadioButtonMenuItem buttRandom	   	= null;
	private  JRadioButtonMenuItem buttInitHidden	= null;
	private  JLabel 			  jLabelInitText	= null;
	private  JToolBar 			  jToolBarInit  	= null;
	private  ButtonGroup 		  buttGroupInit 	= null;
	
	private  JPanel 	jScrollBarPanelK    = null;
	private  JScrollBar	jScrollBarK         = null;
	private  JLabel     jLabelK;
	
	private  JPanel 	jScrollBarPanelItMax    = null;
	private  JScrollBar	jScrollBarItMax         = null;
	private  JLabel     jLabelItMax;
	
	private  JPanel 	jScrollBarPanelEps    = null;
	private  JScrollBar	jScrollBarEps         = null;
	private  JLabel     jLabelEps;
	
	private  JRadioButtonMenuItem buttOrigCol 	   = null;
	private  JRadioButtonMenuItem buttEquiCol      = null;
	private  JRadioButtonMenuItem buttOutColHidden = null;
	private  JLabel 			  jLabelOutCol	   = null;
	private  JToolBar 			  jToolBarOutCol   = null;
	private  ButtonGroup 		  buttGroupOutCol  = null;
	/**
	 * constructor
	 */
	public IqmKMeansGUI() {

	}


	/**
	 * This method sets the current parameter block to the argument
	 * @param ParameterBlockJAI pb
	 *
	 */
	@Override
	public void setParameterBlock(ParameterBlockJAI arg){
		pb = arg;
		IqmTools.setCurrParameterBlockJAI(pb);	
	}
	/**
	 * This method sets the current parameter block
	 * The individual values of the GUI current ParameterBlock
	 *
	 */
	@Override
	public void setParameterBlock(){
		if (buttEven.isSelected())     		pb.setParameter("Init", 0);
		if (buttRandomSample.isSelected())  pb.setParameter("Init", 1);
		if (buttRandom.isSelected())    	pb.setParameter("Init", 2);
		
		pb.setParameter("nK", nK);
		pb.setParameter("ItMax", itMax);
		pb.setParameter("Eps", eps);
		
		if (buttOrigCol.isSelected())  pb.setParameter("Out", 0);
		if (buttEquiCol.isSelected())  pb.setParameter("Out", 1);
		
		IqmTools.setCurrParameterBlockJAI(pb);	
	}
	
	/**
	 * This method sets the current parameter values
	 */
	@Override
	public void setParameterValues(){
		int idx = IqmTools.getCurrManagerImgIndex();
	    PlanarImage pi = Tank.getCurrentTankImageAt(idx); 
	       if (pi == null){
	    	   System.out.println("IqmKMeansGUI: Current image not defined");
	    	   return;
	       }
        String type = IqmTools.getImgTyp(pi);

		buttInitHidden.setSelected(true);
		if (pb.getIntParameter("Init") == 0 ) buttEven.setSelected(true);		
		if (pb.getIntParameter("Init") == 1 ) buttRandomSample.setSelected(true);		
		if (pb.getIntParameter("Init") == 2 ) buttRandom.setSelected(true);
				
		nK = pb.getIntParameter("nK");
		jScrollBarK.removeAdjustmentListener(this);
		jScrollBarK.setValue(nK);
		jScrollBarK.addAdjustmentListener(this);
		jLabelK.setText  ("k: " + nK);
		
		itMax = pb.getIntParameter("ItMax");
		jScrollBarItMax.removeAdjustmentListener(this);
		jScrollBarItMax.setValue(itMax);
		jScrollBarItMax.addAdjustmentListener(this);
		jLabelItMax.setText  ("itMax: " + itMax);
		
		eps = pb.getDoubleParameter("Eps");
		jScrollBarEps.removeAdjustmentListener(this);
		jScrollBarEps.setValue((int) (Math.log10(eps)+ 7d));
		jScrollBarEps.addAdjustmentListener(this);
		jLabelEps.setText  ("eps: " + eps);	
		
		if (pb.getIntParameter("Out") == 0 ) buttOrigCol.setSelected(true);		
		if (pb.getIntParameter("Out") == 1 ) buttEquiCol.setSelected(true);		

	}

	/**
	 * This method creates and shows the GUI
	 */
	@Override
	public void createIqmOperatorGUI() {
		//opGUIFrame = new ImgProcFuncJFrame();  //actionPerforemd events werden in dieser Klasse abgehandelt
		//opGUIFrame = new IqmKMeansGUI();      //actionPerforemd events werden in dieser Klasse abgehandelt
		//this.getJContentPane();
		this.initialize(); //Aufruf von ImgProcFuncJFrame
		this.setTitle("KMeans");
		//PlanarImage pi = Tank.getCurrentTankImageAt(IqmTools.getCurrManagerImgIndex());
		//int numBands = pi.getNumBands();
		//Dimension dim = this.getSize();
		//this.setSize(dim.width, dim.height + 100);
		//this.setPreferredSize(new Dimension(800, 600));
		this.getJContentPane().add(getJLabelInitText(),   getGridBagConstraintsInitText());
		this.getJContentPane().add(getJToolBarInit(),     getGridBagConstraintsButtonGroupInit());
		this.getJContentPane().add(getJScrollBarK(),      getGridBagConstraintsK());
		this.getJContentPane().add(getJScrollBarItMax(),  getGridBagConstraintsItMax());
		this.getJContentPane().add(getJScrollBarEps(),    getGridBagConstraintsEps());
		this.getJContentPane().add(getJLabelOutCol(),     getGridBagConstraintsOutCol());
		this.getJContentPane().add(getJToolBarOutCol(),   getGridBagConstraintsButtonGroupOutCol());

	
		this.pack();
		//this.repaint();
		if (pb == null) pb = new ParameterBlockJAI("IqmKMeans");  //nur wenn das erste mal aufgerufen
		//pb = new ParameterBlockJAI("iqmkmeans"); //immer der default Block
		IqmTools.setCurrParameterBlockJAI(pb);
		setParameterValues();
	}

	//------------------------------------------------------------------------------
	private  GridBagConstraints getGridBagConstraintsInitText(){
		GridBagConstraints gridBagConstraintsInitText = new GridBagConstraints();
		gridBagConstraintsInitText.gridx = 1;
		gridBagConstraintsInitText.gridy = 4;
		//gridBagConstraintsInitText.gridwidth = 3;
		gridBagConstraintsInitText.insets = new Insets(15,15,0,0);  //top, left bottom right
		gridBagConstraintsInitText.fill = GridBagConstraints.BOTH;
		return gridBagConstraintsInitText;
	}
	private  GridBagConstraints getGridBagConstraintsButtonGroupInit(){
		GridBagConstraints gridBagConstraintsButtonGroupInit = new GridBagConstraints();
		gridBagConstraintsButtonGroupInit.gridx = 2;
		gridBagConstraintsButtonGroupInit.gridy = 4;
		gridBagConstraintsButtonGroupInit.gridwidth = 2;
		gridBagConstraintsButtonGroupInit.insets = new Insets(10,0,0,10);  //top, left bottom right
		gridBagConstraintsButtonGroupInit.fill = GridBagConstraints.BOTH;
		return gridBagConstraintsButtonGroupInit;
	}
	private  GridBagConstraints getGridBagConstraintsK(){
		GridBagConstraints gridBagConstraintsK = new GridBagConstraints();
		gridBagConstraintsK.gridx = 1;
		gridBagConstraintsK.gridy = 5;
		gridBagConstraintsK.gridwidth = 3;
		gridBagConstraintsK.insets = new Insets(10,0,0,0);  //top, left bottom right
		//gridBagConstraintsK.fill = GridBagConstraints.BOTH;
		return gridBagConstraintsK;
	}
	private  GridBagConstraints getGridBagConstraintsItMax(){
		GridBagConstraints gridBagConstraintsItMax = new GridBagConstraints();
		gridBagConstraintsItMax.gridx = 1;
		gridBagConstraintsItMax.gridy = 6;
		gridBagConstraintsItMax.gridwidth = 3;
		gridBagConstraintsItMax.insets = new Insets(10,0,0,0);  //top, left bottom right
		//gridBagConstraintsItMax.fill = GridBagConstraints.BOTH;
		return gridBagConstraintsItMax;
	}
	private  GridBagConstraints getGridBagConstraintsEps(){
		GridBagConstraints gridBagConstraintsEps = new GridBagConstraints();
		gridBagConstraintsEps.gridx = 1;
		gridBagConstraintsEps.gridy = 7;
		gridBagConstraintsEps.gridwidth = 3;
		gridBagConstraintsEps.insets = new Insets(10,0,0,0);  //top, left bottom right
		//gridBagConstraintsEps.fill = GridBagConstraints.BOTH;
		return gridBagConstraintsEps;
	}
	private  GridBagConstraints getGridBagConstraintsOutCol(){
		GridBagConstraints gridBagConstraintsOutCol = new GridBagConstraints();
		gridBagConstraintsOutCol.gridx = 1;
		gridBagConstraintsOutCol.gridy = 8;
		//gridBagConstraintsOutCol.gridwidth = 3;
		gridBagConstraintsOutCol.insets = new Insets(15,15,0,0);  //top, left bottom right
		gridBagConstraintsOutCol.fill = GridBagConstraints.BOTH;
		return gridBagConstraintsOutCol;
	}
	private  GridBagConstraints getGridBagConstraintsButtonGroupOutCol(){
		GridBagConstraints gridBagConstraintsButtonGroupOutCol = new GridBagConstraints();
		gridBagConstraintsButtonGroupOutCol.gridx = 2;
		gridBagConstraintsButtonGroupOutCol.gridy = 8;
		gridBagConstraintsButtonGroupOutCol.gridwidth = 2;
		gridBagConstraintsButtonGroupOutCol.insets = new Insets(10,0,20,10);  //top, left bottom right
		gridBagConstraintsButtonGroupOutCol.fill = GridBagConstraints.BOTH;
		return gridBagConstraintsButtonGroupOutCol;
	}


	//------------------------------------------------------------------------------------------------------------------
	/**
	 * This method updates the GUI if needed
	 * This method overrides IqmOperatorJFrame
	 */
	@Override
	public void updateIqmOperatorGUI(){
	
	}
	/**
	 * This method initializes jLabelInitText	
	 * @return javax.swing.JLabel	
	 */
	private  JLabel getJLabelInitText() {
		if (jLabelInitText == null) {
			jLabelInitText = new JLabel();
			jLabelInitText.setText("Initial values:");
		}
		return jLabelInitText	;
	}
	/**
	 * This method initializes the Option: Even 
	 * 	
	 * @return javax.swing.JRadioButtonMenuItem	
	 */
	private  JRadioButtonMenuItem getJRadioButtonMenuButtEven() {
		//if (buttEven == null) {
			buttEven = new JRadioButtonMenuItem();
			buttEven.setText("Equidistant");
			buttEven.setToolTipText("evenly distributed initial values");
			buttEven.addActionListener(this);
			buttEven.setActionCommand("parameter");
		//}
		return buttEven;
	}
	/**
	 * This method initializes the Option: Random Sample
	 * 	
	 * @return javax.swing.JRadioButtonMenuItem	
	 */
	private  JRadioButtonMenuItem getJRadioButtonMenuButtRandomSample() {
		//if (buttRandomSample == null) {
			buttRandomSample = new JRadioButtonMenuItem();
			buttRandomSample.setText("Random Sample");
			buttRandomSample.setToolTipText("randomly sampled initial values");
			buttRandomSample.addActionListener(this);
			buttRandomSample.setActionCommand("parameter");
		//}
		return buttRandomSample;
	}
	/**
	 * This method initializes the Option: Random
	 * 	
	 * @return javax.swing.JRadioButtonMenuItem	
	 */
	private  JRadioButtonMenuItem getJRadioButtonMenuButtRandom() {
		//if (buttRandom == null) {
			buttRandom = new JRadioButtonMenuItem();
			buttRandom.setText("Random");
			buttRandom.setToolTipText("random initial values");
			buttRandom.addActionListener(this);
			buttRandom.setActionCommand("parameter");
		//}
		return buttRandom;
	}
	/**
	 * This method initializes the hidden option	
	 * 	
	 * @return javax.swing.JRadioButtonMenuItem	
	 */
	private  JRadioButtonMenuItem getJRadioButtonMenuButtInitHidden() {
		//if (buttInitHidden == null) {
			buttInitHidden  = new JRadioButtonMenuItem();
			buttInitHidden .setText("Hidden");
			buttInitHidden.setVisible(false);

		//}
		return buttInitHidden;
	}
	/**
	 * This method initializes jJToolBarBar	
	 * 	
	 * @return javax.swing.JToolBar	
	 */
	private   JToolBar getJToolBarInit() {
//		if (jToolBarInit == null) {
			jToolBarInit = new JToolBar("Options");
			jToolBarInit.setOrientation(1); //
			jToolBarInit.add(getJRadioButtonMenuButtEven());
			jToolBarInit.add(getJRadioButtonMenuButtRandomSample());			
			jToolBarInit.add(getJRadioButtonMenuButtRandom());
			jToolBarInit.add(getJRadioButtonMenuButtInitHidden());

			//jToolBarRGB.addSeparator();
			this.setButtonGroupInit();	//Gruppieren der JRadioButtons
//		}
		return jToolBarInit;
	}
	private  void setButtonGroupInit() {
		//if (ButtonGroup buttGroupInit == null) {
			buttGroupInit = new ButtonGroup();
			buttGroupInit.add(buttEven);
			buttGroupInit.add(buttRandomSample);
			buttGroupInit.add(buttRandom);
			buttGroupInit.add(buttInitHidden);		
	}

	/**
	 * This method initializes jScrollBarK	
	 * @return javax.swing.JScrollBar	
	 */
	private  JPanel getJScrollBarK() {
		if (jScrollBarK	== null) {
			jScrollBarPanelK = new JPanel();	
			jScrollBarPanelK.setLayout(new BorderLayout());
			jScrollBarPanelK.setPreferredSize(new Dimension(250,18));			
			jScrollBarK	= new JScrollBar(JScrollBar.HORIZONTAL);
			jScrollBarK.setToolTipText("number of cluster centers");
			jScrollBarK.setValues(2, 0, 2, 100);
			jScrollBarK.addAdjustmentListener(this);
			jLabelK    = new JLabel();
			jLabelK.setText  ("k: " + 2);
			jLabelK.setPreferredSize(new Dimension(75,10));
			jScrollBarPanelK.add(jLabelK,     BorderLayout.WEST);
			jScrollBarPanelK.add(jScrollBarK, BorderLayout.CENTER);		
		}
		return jScrollBarPanelK	;
	}
	/**
	 * This method initializes jScrollBarItMax	
	 * @return javax.swing.JScrollBar	
	 */
	private  JPanel getJScrollBarItMax() {
		if (jScrollBarItMax	== null) {
			jScrollBarPanelItMax = new JPanel();	
			jScrollBarPanelItMax.setLayout(new BorderLayout());
			jScrollBarPanelItMax.setPreferredSize(new Dimension(250,18));			
			jScrollBarItMax	= new JScrollBar(JScrollBar.HORIZONTAL);
			jScrollBarItMax.setToolTipText("maximal number of iterations");
			jScrollBarItMax.setValues(20, 0, 20, 1000);
			jScrollBarItMax.setUnitIncrement(20);
			jScrollBarItMax.addAdjustmentListener(this);
			jLabelItMax    = new JLabel();
			jLabelItMax.setText  ("itMax: " + 10);
			jLabelItMax.setPreferredSize(new Dimension(75,10));
			jScrollBarPanelItMax.add(jLabelItMax,     BorderLayout.WEST);
			jScrollBarPanelItMax.add(jScrollBarItMax, BorderLayout.CENTER);		
		}
		return jScrollBarPanelItMax	;
	}
	/**
	 * This method initializes jScrollBarEps	
	 * @return javax.swing.JScrollBar	
	 */
	private  JPanel getJScrollBarEps() {
		if (jScrollBarEps	== null) {
			jScrollBarPanelEps = new JPanel();	
			jScrollBarPanelEps.setLayout(new BorderLayout());
			jScrollBarPanelEps.setPreferredSize(new Dimension(250,18));			
			jScrollBarEps	= new JScrollBar(JScrollBar.HORIZONTAL);
			jScrollBarEps.setToolTipText("accuracy");
			jScrollBarEps.setValues(6, 0, 1, 10);  //1 bis 10 wird in 10hoch -6 bis 10 hoch+3 umgewandelt
			jScrollBarEps.addAdjustmentListener(this);
			jLabelEps    = new JLabel();
			eps = Math.pow(10d, (double)(jScrollBarEps.getValue()-7));
			jLabelEps.setText  ("eps: " + eps);
			jLabelEps.setPreferredSize(new Dimension(75,10));
			jScrollBarPanelEps.add(jLabelEps,     BorderLayout.WEST);
			jScrollBarPanelEps.add(jScrollBarEps, BorderLayout.CENTER);		
		}
		return jScrollBarPanelEps	;
	}
	
	/**
	 * This method initializes jLabelOutCol	
	 * @return javax.swing.JLabel	
	 */
	private  JLabel getJLabelOutCol() {
		if (jLabelOutCol == null) {
			jLabelOutCol = new JLabel();
			jLabelOutCol.setText("Output Color:");
		}
		return jLabelOutCol	;
	}
	/**
	 * This method initializes the Option: OrigCol 
	 * 	
	 * @return javax.swing.JRadioButtonMenuItem	
	 */
	private  JRadioButtonMenuItem getJRadioButtonMenuButtOrigCol() {
		//if (buttOrigCol == null) {
			buttOrigCol = new JRadioButtonMenuItem();
			buttOrigCol.setText("Calculated clusters");
			buttOrigCol.setToolTipText("the calculated clusters ares used as output colors");
			buttOrigCol.addActionListener(this);
			buttOrigCol.setActionCommand("parameter");
		//}
		return buttOrigCol;
	}
	/**
	 * This method initializes the Option: equidistant colors
	 * 	
	 * @return javax.swing.JRadioButtonMenuItem	
	 */
	private  JRadioButtonMenuItem getJRadioButtonMenuButtEquiCol() {
		//if (buttEquiCol == null) {
			buttEquiCol = new JRadioButtonMenuItem();
			buttEquiCol.setText("Equidistant colors");
			buttEquiCol.setToolTipText("equidistant colors are used as output colors ");
			buttEquiCol.addActionListener(this);
			buttEquiCol.setActionCommand("parameter");
		//}
		return buttEquiCol;
	}
	
	/**
	 * This method initializes the hidden option	
	 * 	
	 * @return javax.swing.JRadioButtonMenuItem	
	 */
	private  JRadioButtonMenuItem getJRadioButtonMenuButtOutColHidden() {
		//if (buttOutColHidden == null) {
			buttOutColHidden  = new JRadioButtonMenuItem();
			buttOutColHidden .setText("Hidden");
			buttOutColHidden.setVisible(false);

		//}
		return buttOutColHidden;
	}
	/**
	 * This method initializes jJToolBarBar	
	 * 	
	 * @return javax.swing.JToolBar	
	 */
	private   JToolBar getJToolBarOutCol() {
//		if (jToolBarOutCol == null) {
			jToolBarOutCol = new JToolBar("Options");
			jToolBarOutCol.setOrientation(1); //
			jToolBarOutCol.add(getJRadioButtonMenuButtOrigCol());
			jToolBarOutCol.add(getJRadioButtonMenuButtEquiCol());			
			jToolBarOutCol.add(getJRadioButtonMenuButtOutColHidden());

			//jToolBarRGB.addSeparator();
			this.setButtonGroupOutCol();	//Gruppieren der JRadioButtons
//		}
		return jToolBarOutCol;
	}
	private  void setButtonGroupOutCol() {
		//if (ButtonGroup buttGroupOutCol == null) {
			buttGroupOutCol = new ButtonGroup();
			buttGroupOutCol.add(buttOrigCol);
			buttGroupOutCol.add(buttEquiCol);
			buttGroupOutCol.add(buttOutColHidden);		
	}
	
	//--------------------------------------------------------------------------------------------
	public void actionPerformed(ActionEvent e) {
		//System.out.println("IqmKMeansGUI: event e: " +e.getActionCommand());
		if ("reset".equals(e.getActionCommand())) {
			ParameterBlockJAI pb = new ParameterBlockJAI("IqmKMeans".toLowerCase());
			IqmTools.setCurrParameterBlockJAI(pb);
			this.setParameterBlock(pb);
			this.setParameterValues();
			//this.updateIqmOperatorGUI();  //if necessary here or some lines above
			this.reset();
		}
		if ("parameter".equals(e.getActionCommand())) {
			this.setParameterBlock();
			//this.updateIqmOperatorGUI();  //if necessary here or some lines above
		}
		//preview if selected
		if (this.isAutoPreviewSelected()){
			this.showPreview();
		}

	}
	@Override
	public void adjustmentValueChanged(AdjustmentEvent e) {
		Object obE = e.getSource();
		if (obE instanceof JScrollBar){
			jScrollBarK.removeAdjustmentListener(this);
			jScrollBarItMax.removeAdjustmentListener(this);
			jScrollBarEps.removeAdjustmentListener(this);
			
			//ScrollBars-----------------------------------------------------------------------------
			if (obE == jScrollBarK){
				nK = jScrollBarK.getValue();
				jLabelK.setText  ("k: " + nK);
			}
			if (obE == jScrollBarItMax){
				itMax = jScrollBarItMax.getValue();
				jLabelItMax.setText  ("itMax: " + itMax);
			}
			if (obE == jScrollBarEps){
				eps = Math.pow(10d, (double)(jScrollBarEps.getValue()-7));
				System.out.println("IqmKMeansGUI: jScrollBarEps.getValue()" +jScrollBarEps.getValue() );
//				System.out.println("IqmKMeansGUI: eps " + eps );
//				if (jScrollBarEps.getValue() == 2) eps =  Math.pow(10d, -5d);  //10 hoch -5 wird nicht richtig dargestellt??
//				System.out.println("IqmKMeansGUI: eps " + eps );
				jLabelEps.setText  ("eps: " + eps);
			}
			jScrollBarK.addAdjustmentListener(this);
			jScrollBarItMax.addAdjustmentListener(this);
			jScrollBarEps.addAdjustmentListener(this);
	
		}
		this.setParameterBlock();
		//this.updateIqmOperatorGUI();  //if necessary here or some lines above
		
		//preview if selected
		if (this.isAutoPreviewSelected()){
			this.showPreview();
		}
	}
	//-------------------------------------------------------------------------------------------------
	public static void main() {

		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				IqmKMeansGUI gui = new IqmKMeansGUI();
				gui.createIqmOperatorGUI();

			}
		});
	}



	
}//END
